Skip to content

Bugfix: SharedUserInterfaceSystem stores and applies BUI states in order. - #6829

Merged
Princess-Cheeseballs merged 8 commits into
space-wizards:masterfrom
whatston3:2026-07-20-state-stream
Jul 23, 2026
Merged

Bugfix: SharedUserInterfaceSystem stores and applies BUI states in order.#6829
Princess-Cheeseballs merged 8 commits into
space-wizards:masterfrom
whatston3:2026-07-20-state-stream

Conversation

@whatston3

@whatston3 whatston3 commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

What the title says.

Related issues

From the solution in #6789, instead of using the most recent state in every update, we cache the intermediate states (appending a third element into the tuple) and update with each intermediate value when predicting. In addition, all open operations are only opens.

This is particularly naive, and I don't know what lies in between the state population and that Update call.

There's also a lingering BUI.UpdateState/Update call in UISystem.SetUiState that should possibly be deferred.

I hate that the list Remove call uses an explicit null value, but all open/close additions should be null.

Small video of the PDA working with this change:

pda-fix.mp4

@whatston3
whatston3 requested a review from DrSmugleaf as a code owner July 20, 2026 12:05
@whatston3 whatston3 changed the title Bugfix: SharedUserInterfaceSystem stores and uses intermediate BUI states Bugfix: SharedUserInterfaceSystem stores and applies BUI states in order. Jul 20, 2026
@eoineoineoin

Copy link
Copy Markdown
Member

Looks like this new bug was my fault - whoops. I'm a little concerned about this, though:

In addition, all open operations are only opens.

Even before #6789, the open operations were doing a bui.Open(), bui.UpdateState() and bui.Update(), hence the slightly awkward conditions. When I was making that change, it seemed pretty important to preserve that behaviour - there are ComponentStartup and PlayerAttached events which will try to open UIs, but look like they're not going to get an UpdateState message, so skipping the updates may break UIs in those cases.

@whatston3

whatston3 commented Jul 20, 2026

Copy link
Copy Markdown
Contributor Author

Even before #6789, the open operations were doing a bui.Open(), bui.UpdateState() and bui.Update(), hence the slightly awkward conditions. When I was making that change, it seemed pretty important to preserve that behaviour - there are ComponentStartup and PlayerAttached events which will try to open UIs, but look like they're not going to get an UpdateState message, so skipping the updates may break UIs in those cases.

The thing is that you break the sequence of state updates if you give it the latest state, and as far as I know, you don't conveniently have the state at the time. If that's easy to get (is it inside of the UIComponent for the relevant key?) then it could be shoved into the Open [command when it's queued], no problem, but you probably should not break the sequence of state updates as they happen (hence the concerns w.r.t. UISystem.SetUiState)

@whatston3

Copy link
Copy Markdown
Contributor Author

This feels much worse than before #6789. Closing for now and recommending to revert #6789.

Might look into underlying issues more, but this is a dead-end unless I'm missing something.

@whatston3 whatston3 closed this Jul 20, 2026
@whatston3 whatston3 reopened this Jul 22, 2026
@whatston3

whatston3 commented Jul 22, 2026

Copy link
Copy Markdown
Contributor Author

After a handful of tests, it seems to behave the same as it did before #6789 (good lord).

Reopening this.

@Princess-Cheeseballs

Copy link
Copy Markdown
Member

Remind me to review tonight and get it mergeable so we can do a patch for the current engine version

@deltanedas

Copy link
Copy Markdown
Contributor

tested, works

@Princess-Cheeseballs Princess-Cheeseballs self-assigned this Jul 23, 2026

@Princess-Cheeseballs Princess-Cheeseballs left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code makes sense. At worst I could nitpick the dictionary method being TryGetValue instead of GetValueOrDefault but It's not a big deal at all.

@whatston3

Copy link
Copy Markdown
Contributor Author

Code makes sense. At worst I could nitpick the dictionary method being TryGetValue instead of GetValueOrDefault but It's not a big deal at all.

Should be changed.

@Princess-Cheeseballs
Princess-Cheeseballs added this pull request to the merge queue Jul 23, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to no response for status checks Jul 23, 2026
@Princess-Cheeseballs
Princess-Cheeseballs added this pull request to the merge queue Jul 23, 2026
@Princess-Cheeseballs
Princess-Cheeseballs removed this pull request from the merge queue due to a manual request Jul 23, 2026
@Princess-Cheeseballs
Princess-Cheeseballs merged commit c766e79 into space-wizards:master Jul 23, 2026
7 checks passed
Princess-Cheeseballs pushed a commit that referenced this pull request Jul 23, 2026
…der. (#6829)

* store intermediate bui states

* exception printout, remove redundant check

* Set state on Open

* trygetvalue defaults, you dingus

* fix string interpolation bug

* queue in SetUiState

* queue in SetUiState regardless

* TryGetValue->GetValueOrDefault

(cherry picked from commit c766e79)
@deltanedas

Copy link
Copy Markdown
Contributor

pretty sure this broke gas filter ui and cargo shuttle

if you open gas filter it wont update anything until you e.g. change gas
i imagine its because of using before activatable ui event for setting ui state

@whatston3

Copy link
Copy Markdown
Contributor Author

pretty sure this broke gas filter ui and cargo shuttle

if you open gas filter it wont update anything until you e.g. change gas i imagine its because of using before activatable ui event for setting ui state

Apologies, then. I'll look into it.

@whatston3
whatston3 deleted the 2026-07-20-state-stream branch July 23, 2026 21:39
@whatston3

Copy link
Copy Markdown
Contributor Author

pretty sure this broke gas filter ui and cargo shuttle

if you open gas filter it wont update anything until you e.g. change gas i imagine its because of using before activatable ui event for setting ui state

you're gonna love the fix for this one

@eoineoineoin

Copy link
Copy Markdown
Member

Is everyone happy with this solution and the associated hotfix?

I did a little digging, as the claim "we cache the intermediate states" seemed kinda funny to me, and I didn't see how #6789 would have broken it. What's happening is that the PDABoundUserInterface sends multiple different implementations of BoundUserInterfaceState to update subsets of the UI. But the SharedUserInterfaceSystem is written in a way that assumes a single BoundUserInterfaceState will describe the whole UI. i.e., it contains code like:

Entity<UserInterfaceComponent> ent = ...;
BoundUserInterfaceState buiState = ...
...
ent.Comp.States[key] = buiState;

So, relying on the stored state for some key is not a reliable way to reconstruct the UI. I suspect there's probably a lingering bug here.

If we're not all completely happy with this fix, I'll spend some time this weekend to figure out how this could be improved.

pull Bot pushed a commit to weaversam8/RobustToolbox that referenced this pull request Aug 4, 2026
…ards#6840) (space-wizards#6900)

* Revert "Hotfix: pass last state in SharedUserInterfaceSystem.EnsureClientBui (space-wizards#6840)"

This reverts commit 08b3257.

* Revert "Bugfix: SharedUserInterfaceSystem stores and applies BUI states in order. (space-wizards#6829)"

This reverts commit c766e79.

* Revert "Defer UI operations until UI system runs frame update (space-wizards#6789)"

This reverts commit f44d7e0.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants